#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#include "ipv4.h"
#include "ethqos.h"
#include "eth.h"
#include "udp.h"



/**
 * @brief   计算IP校验和
 * @param[in] data 待计算校验和的数据
 * @param[in] len 待计算校验和的数据长度
 * @return  校验和
 */
static uint16_t ip_checksum(const void *data, size_t len) {
    const uint16_t *ptr = data;
    uint32_t sum = 0;
    while (len > 1) {
        sum += *ptr++;
        len -= 2;
    }
    if (len == 1) sum += *(uint8_t*)ptr;
    while (sum >> 16) sum = (sum & 0xFFFF) + (sum >> 16);
    return ~sum;
}

/**
 * @brief   构造IPv4回复包
 * @param[in] ip 收到的IPv4包头
 * @param[out] reply_buf 回复包缓冲区
 * @param[in] reply_payload_len 回复包负载长度
 * @return  0：成功；其他：失败
 */
int ipv4_make_reply(IPv4Header *ip,void * reply_buf,uint16_t reply_payload_len){

    IPv4Header *reply_ip = (IPv4Header*)(reply_buf + sizeof(EthernetHeader));
    memcpy(reply_ip->dest_ip, ip->src_ip, 4);
    memcpy(reply_ip->src_ip, DEV_IP, 4);
    reply_ip->ver_ihl = 0x45;        // IPv4 + 5 words
    reply_ip->protocol = 17;         // UDP
    reply_ip->ttl = 64;
    reply_ip->total_length = htons(sizeof(IPv4Header) + sizeof(UDPHeader) + reply_payload_len);
    
    // 计算IP校验和
    reply_ip->checksum = 0;
    reply_ip->checksum = ip_checksum(reply_ip, sizeof(IPv4Header));

    return 0;

}